/**
 * 
 */
package com.dragonwarriors.player;

import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;

import com.ahq.main.AHQApplet;
import com.ahq.main.H1HighlightBorder;
import com.ahq.main.H1SelectionBorder;
import com.dalonedrau.d20.Diceroller;
import com.dalonedrau.jogl.engine.Action;
import com.dalonedrau.jogl.engine.GameApplet;
import com.dalonedrau.jogl.engine.GlobalConsts;
import com.dalonedrau.jogl.engine.ProjectConstants;
import com.dalonedrau.jogl.opengl.sprite.SpriteBase;
import com.dalonedrau.jogl.opengl.sprite.SpriteImageObjectFactory;
import com.dalonedrau.jogl.opengl.ui.Button;
import com.dalonedrau.jogl.opengl.ui.GuiComponent;
import com.dalonedrau.jogl.opengl.ui.Label;
import com.dalonedrau.jogl.opengl.ui.TextField;
import com.dalonedrau.jogl.opengl.ui.UIFactory;
import com.dalonedrau.jogl.opengl.ui.border.EmptyBorder;
import com.dalonedrau.jogl.opengl.ui.border.FlexibleImageBorder;
import com.dalonedrau.jogl.opengl.ui.border.GradientBackgroundBorder;
import com.dalonedrau.jogl.opengl.ui.border.GuiBorder;
import com.dalonedrau.jogl.opengl.ui.border.VXBorder;
import com.dalonedrau.jogl.opengl.ui.panel.CardPanel;
import com.dalonedrau.jogl.opengl.ui.panel.LandscapePagePanel;
import com.dalonedrau.jogl.opengl.ui.panel.PagePanel;
import com.dalonedrau.jogl.opengl.ui.panel.Panel;
import com.dalonedrau.jogl.opengl.ui.panel.PortraitPagePanel;
import com.dalonedrau.jogl.util.UtilityMethods;
import com.dalonedrau.pool.PooledStringBuilder;
import com.dalonedrau.pool.StringBuilderPool;

final class CharacteristicsOptions extends LandscapePagePanel {
	/** the "Done" button. */
	private Button	btn;
	/** Creates a new instance of {@link GenderOptions}. */
	CharacteristicsOptions() {
		super(Panel.LANDSCAPE_CENTER);
		super.setHorizontalAlignment(Panel.TEXT_JUSTIFY);
		super.setMinimumWidth(
				DWPCViewer.getInstance().getPreferredSize().width - 10);

		super.addChild(UtilityMethods.getInstance().getSpacer(1, 38));
		Button b1 = UIFactory.getInstance().getStandardButton("Roll Scores");
		b1.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().setCharacteristics(
						DWPlayer.getInstance().rollCharacteristicScore(),
						DWPlayer.getInstance().rollCharacteristicScore(),
						DWPlayer.getInstance().rollCharacteristicScore(),
						DWPlayer.getInstance().rollCharacteristicScore(),
						DWPlayer.getInstance().rollCharacteristicScore()
						);
				btn.setActive(true);
			}
		});
		b1.setHighlightable(true);
		b1.setHighlightBorder(new H1HighlightBorder());
		super.addChild(b1);
		super.addChild(UtilityMethods.getInstance().getSpacer(1, 38));

		btn = UIFactory.getInstance().getStandardButton("Done");
		btn.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().nextStep();
			}
		});
		btn.setHighlightable(true);
		btn.setHighlightBorder(new H1HighlightBorder());
		btn.setActive(false);
		super.addChild(btn);
		super.addChild(UtilityMethods.getInstance().getSpacer(1, 38));

		Button b2 = UIFactory.getInstance().getStandardButton("Change Gender");
		b2.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().prevStep();
			}
		});
		b2.setHighlightable(true);
		b2.setHighlightBorder(new H1HighlightBorder());
		super.addChild(b2);
	}
}

/**
 * The character creation screen.<br>
 * |-------------------------|<br>
 * | TITLE |<br>
 * |-------------------------|<br>
 * | Steps | Options | Info |<br>
 * | |---------| |<br>
 * | Panel | Char | Panel |<br>
 * | | Viewer | |<br>
 * |-------|---------|-------|<br>
 * @author Donald
 */
public final class DWCharCreationScreen extends PortraitPagePanel {
	/** the one and only instance of the <code>Sprite</code> class. */
	private static DWCharCreationScreen	instance;
	/**
	 * Gives access to the singleton instance of {@link DWCharCreationScreen}.
	 * @return {@link DWCharCreationScreen}
	 */
	public static DWCharCreationScreen getInstance() {
		if (DWCharCreationScreen.instance == null) {
			DWCharCreationScreen.instance = new DWCharCreationScreen();
			DWCharCreationScreen.instance.init();
		}
		return DWCharCreationScreen.instance;
	}
	/** the helper text label. */
	private Label					lblHelper;
	private MSGWindow3				msg2;
	private MSGWindow4				msg3;
	private MSGWindowElementalists	msgElements;
	private MSGWindowElementalists2	msgElements2;
	private DWCharacter				pc		= new DWCharacter();
	/** the helper text panel. */
	private PagePanel				pnlHelper;
	/** the professional options panel. */
	private ProfessionOptions pnlProfessions;
	/** the middle panel. */
	private PagePanel				pnlMiddle;
	/** the option panel. */
	private CardPanel				pnlOptions;
	/** the panel displaying each step of the character creation process. */
	private StepsPanel				pnlSteps;
	/** the panel containing the screen title. */
	private PagePanel				pnlTitle;
	/** the current step in the process. */
	private int						step	= 0;
	/** Hidden constructor. */
	private DWCharCreationScreen() {
		super(Panel.LANDSCAPE_CENTER);
	}
	private void checkStep() {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		switch (step) {
		case 1:
			pnlOptions.displayChild("gender");
			sb.append("A character's gender has no effect on characteristic ");
			sb.append("scores; a woman can take the head of a dragon as ");
			sb.append("readily as a man.");
			break;
		case 2:
			pnlOptions.displayChild("characteristics");
			sb.append("Each character is initially defined by their scores ");
			sb.append("in five characteristics: STRENGTH, REFLEXES, ");
			sb.append("INTELLIGENCE, PSYCHIC TALENT, and LOOKS. These scores ");
			sb.append("range from a minimum of 3 to a maximum of 18.");
			break;
		case 3:
			pnlOptions.displayChild("professions");
			sb.append("There are seven Professions to which an ");
			sb.append("adventurer may belong.");
			break;
		}
		pnlSteps.setArrow(step);
		setHelperText(sb.toString());
		sb.returnToPool();
	}
	/**
	 * Creates the middle row.
	 * @throws Exception if an error occurs
	 */
	private void createMiddleRow() throws Exception {
		pnlMiddle = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		// 199px wide
		pnlSteps = new StepsPanel();
		// 392px wide
		Panel p1 = getMiddleColumn();
		pnlSteps.setMinimumHeight(p1.getPreferredSize().height);
		PagePanel p2 = getHelperPanel();
		p2.setMinimumHeight(p1.getPreferredSize().height);

		pnlMiddle.addChild(pnlSteps);
		pnlMiddle.addChild(p1);
		pnlMiddle.addChild(p2);
	}
	/**
	 * Creates the options panel.
	 * @throws Exception if an error occurs
	 */
	private void createOptionsPanel() throws Exception {
		pnlOptions = new CardPanel();
		// add border - 10px wide by 10px high
		pnlOptions.setBorder(
				DWCharCreationScreen.getInstance().getOptionsBorder());
		pnlOptions.addChild("start", new StartOptions());
		pnlOptions.addChild("gender", new GenderOptions());
		pnlOptions.addChild("characteristics", new CharacteristicsOptions());
		pnlProfessions = new ProfessionOptions();
		pnlOptions.addChild("professions", pnlProfessions);
		pnlOptions.displayChild("start");
	}
	/**
	 * Creates the title row.
	 * @throws Exception if an error occurs
	 */
	private void createTitleRow() throws Exception {
		pnlTitle = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		Label lbl = UIFactory.getInstance().getStandardH1Label(
				"Create A New Character");
		pnlTitle.addChild(lbl);
		// add border - 16px wide by 13px high
		pnlTitle.setBorder(new FlexibleImageBorder(
				new int[] {
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_bl_full"), // bottom-l
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_br_0"), // bottom-r
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_b_1"), // bottom
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_border_tl"), // top-left
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_border_tr"), // top-right
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_border_t"), // top
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_border_l"), // left
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_border_r") // right
				},
				new int[] {
						GlobalConsts.INT_008, // top
						GlobalConsts.INT_008, // left
						GlobalConsts.INT_005, // bottom
						GlobalConsts.INT_008 // right
				}
				));
	}
	public int getGender() {
		return pc.getGender();
	}
	private PagePanel getHelperPanel() throws Exception {
		pnlHelper = new LandscapePagePanel(Panel.LANDSCAPE_TOP);
		pnlHelper.setMinimumWidth(199);
		pnlHelper.setMaximumWidth(199);
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		sb.append("This Wizard will guide you through the process of ");
		sb.append("creating a character. To exit at any time, please press ");
		sb.append("'Cancel' on the far left.");
		lblHelper = UIFactory.getInstance().getStandardH2Label(sb.toString());
		lblHelper.setMaximumWidth(186);
		pnlHelper.addChild(lblHelper);
		// add panel's border, 13px wide, 13px high
		pnlHelper.setBorder(new FlexibleImageBorder(
				new int[] {
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_bl_half_2"), // bottom-l
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_border_br"), // bottom-right
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_border_b"), // bottom
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_tl_half"), // top-l
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_tr_0"), // top-right
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_t_1"), // top
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_l"), // left
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_border_r") // right
				},
				new int[] {
						GlobalConsts.INT_005, // top
						GlobalConsts.INT_005, // left
						GlobalConsts.INT_008, // bottom
						GlobalConsts.INT_008 // right
				}
				));
		sb.returnToPool();
		return pnlHelper;
	}
	/**
	 * Gets the PC's intelligence score.
	 * @return int
	 */
	public int getIntelligence() {
		return pc.getFullIntelligence();
	}
	private Panel getMiddleColumn() throws Exception {
		PagePanel p = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		createOptionsPanel();
		p.addChild(pnlOptions);
		p.addChild(DWPCViewer.getInstance());
		return p;
	}
	/**
	 * Gets the border used for the options pane.
	 * @return {@link GuiBorder}
	 * @throws Exception if an error occurs
	 */
	public GuiBorder getOptionsBorder() throws Exception {
		return new FlexibleImageBorder(
				new int[] {
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_bl_half"), // b-l
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_br_half"), // b-r
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_b_1"), // bottom
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_tl_half"), // top-l
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_tr_half"), // top-r
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_t_1"), // top
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_l"), // left
						SpriteImageObjectFactory.getInstance()
								.getImageRefId(
										"vx_flex_border_r") // right
				},
				new int[] {
						GlobalConsts.INT_005, // top
						GlobalConsts.INT_005, // left
						GlobalConsts.INT_005, // bottom
						GlobalConsts.INT_005 // right
				});
	}
	/**
	 * Gets the PC's psychic talent score.
	 * @return int
	 */
	public int getPsychicTalent() {
		return pc.getFullPsychicTalent();
	}
	/**
	 * Gets the PC's reflexes score.
	 * @return int
	 */
	public int getReflexes() {
		return pc.getFullReflexes();
	}
	/**
	 * Handles key events on the screen.
	 * @param e the {@link KeyEvent}
	 */
	public void handleKeyEvent(final KeyEvent e) {
		if (step == 2) {
			switch (e.getKeyCode()) {
			case KeyEvent.VK_BACK_SPACE:
				try {
					msg2.removeCharacter();
				} catch (Exception ex) {
					JOGLErrorHandler.getInstance().fatalError(ex);
				}
				break;
			case KeyEvent.VK_SPACE:
				try {
					msg2.addCharacter(e.getKeyChar());
				} catch (Exception ex) {
					JOGLErrorHandler.getInstance().fatalError(ex);
				}
				break;
			default:
				if (Character.isLetterOrDigit(e.getKeyChar())) {
					try {
						msg2.addCharacter(e.getKeyChar());
					} catch (Exception ex) {
						JOGLErrorHandler.getInstance().fatalError(ex);
					}
				}
				break;
			}
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void handleMouseClick(final MouseEvent e, final float x, 
			final float y) {
		switch (step) {
		case 0:
		case 1:
		case 2:
			super.handleMouseClick(e, x, y);
			break;
		case 3:
			if (msgElements.isVisible()) {
				if (msgElements.contains(x, y)) {
					msgElements.handleMouseClick(e, x, y);
				}
			} else if (msgElements2.isVisible()) {
				if (msgElements2.contains(x, y)) {
					msgElements2.handleMouseClick(e, x, y);
				}
			} else {
				super.handleMouseClick(e, x, y);
			}
			break;
		case 4:
			/*
			 * if (msg4a.contains(x, y)) { msg4a.handleMouseClick(x, y); } else
			 * if (pnlSteps.contains(x, y)) { pnlSteps.handleMouseClick(x, y); }
			 */
			super.handleMouseClick(e, x, y);
			break;
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void handleMouseOver(float x, float y) {
		switch (step) {
		case 0:
		case 1:
		case 2:
			super.handleMouseOver(x, y);
			break;
		case 3:
			if (msgElements.isVisible()) {
				if (msgElements.contains(x, y)) {
					msgElements.handleMouseOver(x, y);
				} else {
					msgElements.clearTooltipTimers();
				}
			} else if (msgElements2.isVisible()) {
				if (msgElements2.contains(x, y)) {
					msgElements2.handleMouseOver(x, y);
				} else {
					msgElements.clearTooltipTimers();
				}
			} else {
				super.handleMouseOver(x, y);
				msgElements.clearTooltipTimers();
			}
			break;
		case 4:
			/*
			 * if (msg4a.contains(x, y)) { System.out.println("in 4a");
			 * msg4a.handleMouseOver(x, y); } else if (pnlSteps.contains(x, y))
			 * { System.out.println("in steps"); msg4a.clearTooltipTimers();
			 * pnlSteps.handleMouseOver(x, y); } else {
			 * System.out.println("in nothing"); msg4a.clearTooltipTimers(); }
			 */
			super.handleMouseOver(x, y);
			break;
		}
	}
	/** Initializes the screen. */
	private void init() {
		try {
			super.setBorder(new GradientBackgroundBorder());
			// add the PC viewer as a watcher for this instance
			pc.addWatcher(DWPCViewer.getInstance());
			// create title row

			// 50px spacer
			// super.addChild(UtilityMethods.getInstance().getSpacer(
			// 50, 50));
			// TITLE ROW - 790px wide, 32px high
			createTitleRow();
			createMiddleRow();
			pnlTitle.setMinimumWidth(pnlMiddle.getPreferredSize().width);

			super.addChild(pnlTitle);
			super.addChild(pnlMiddle);

			msg2 = new MSGWindow3();
			msg3 = new MSGWindow4();
			msgElements = new MSGWindowElementalists();
			msgElements.setVisible(false);
			msgElements2 = new MSGWindowElementalists2();
			msgElements2.setVisible(false);
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	public void nextStep() {
		step++;
		checkStep();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void prepareForRendering() throws Exception {
		super.prepareForRendering();
		switch (step) {
		case 0:
		case 1:
		case 2:
			break;
		case 3:
			if (msgElements.getPosition() == null) {
				double x = super.getPosition().getX();
				double y = super.getPosition().getY();
				double z = super.getPosition().getZ() + 1000;
				x += (super.getPreferredSize().width
						- msgElements.getPreferredSize().width) / 2;
				y += (super.getPreferredSize().height
						- msgElements.getPreferredSize().height) / 2;
				msgElements.setPosition(x, y, z);
			}
			if (msgElements2.getPosition() == null) {
				double x = super.getPosition().getX();
				double y = super.getPosition().getY();
				double z = super.getPosition().getZ() + 1000;
				x += (super.getPreferredSize().width
						- msgElements2.getPreferredSize().width) / 2;
				y += (super.getPreferredSize().height
						- msgElements2.getPreferredSize().height) / 2;
				msgElements2.setPosition(x, y, z);
			}
			if (msgElements.isVisible()) {
				msgElements.prepareForRendering();
			} else if (msgElements2.isVisible()) {
				msgElements2.prepareForRendering();
			}
			break;
		case 4:
			/*
			 * if (msg4a.getPosition() == null) { double x =
			 * super.getPosition().getX(); double y =
			 * super.getPosition().getY(); double z = super.getPosition().getZ()
			 * + 1000; x += (super.getPreferredSize().width -
			 * msg4a.getPreferredSize().width) / 2; y +=
			 * (super.getPreferredSize().height -
			 * msg4a.getPreferredSize().height) / 2; msg4a.setPosition(x, y, z);
			 * } msg4a.prepareForRendering();
			 */
			break;
		}
	}
	public void prevStep() {
		step--;
		checkStep();
	}
	/**
	 * Sets the PC's characteristics scores.
	 * @param args the scores
	 */
	public void setCharacteristics(final int... args) {
		pc.setStrength(args[0]);
		pc.setReflexes(args[1]);
		pc.setIntelligence(args[2]);
		pc.setPsychicTalent(args[GlobalConsts.INT_003]);
		pc.setLooks(args[GlobalConsts.INT_004]);

		pc.setFullStrength(args[0]);
		pc.setFullReflexes(args[1]);
		pc.setFullIntelligence(args[2]);
		pc.setFullPsychicTalent(args[GlobalConsts.INT_003]);
		pc.setFullLooks(args[GlobalConsts.INT_004]);

		pnlProfessions.refactor();
		
		pc.setProfession(-1);

		pc.notifyWatchers();
	}
	/**
	 * Sets the PC's gender.
	 * @param gender the chosen gender
	 */
	public void setGender(final int gender) {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		pc.setGender(gender);
		switch (gender) {
		case DWConsts.GENDER_MALE:
			sb.append("The country of Ellesland is a male-dominated society; ");
			sb.append("men can follow any career path of their choosing and ");
			sb.append("expect no adverse reactions from society.");
			break;
		default:
			sb.append("The women of Ellesland are not barred from any ");
			sb.append("profession, but they can experience discrimination if ");
			sb.append("they choose to become ");
			sb.append("adventurers - male knights who refuse to acknowledge ");
			sb.append("a female knight's rank, or female magicians who ");
			sb.append("find themselves denied access to guild libraries ");
			sb.append("are not uncommon.");
			break;
		}
		setHelperText(sb.toString());
		sb.returnToPool();
	}
	private void setHelperText(final String text) {
		lblHelper.setText(text);
		pnlHelper.getPreferredSize().width = 0;
		pnlHelper.getPreferredSize();
	}
	public void setName(final String name) {
		pc.setName(name.toCharArray());
	}
	/**
	 * Sets the PC's profession.
	 * @param profession the profession assigned
	 */
	public void setProfession(final int profession) {
		DWPlayer.getInstance().assignProfession(pc, profession);
		if (profession == DWConsts.PROF_ELEMENTALIST_DARKNESS) {
			pc.setSubsidiaryElementalistSpecializations(
					msgElements2.getElements());
		}
		DWPlayer.getInstance().computeFullStats(pc);
		char[] description = DWConsts.PROFESSION_DESCRIPTIONS[profession];
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		for (int i = 0; i < description.length; i++) {
			sb.append(description[i]);
		}
		setHelperText(sb.toString());
		description = null;
		sb.returnToPool();
	}
	/**
	 * Toggles the display of the elementalist dialog.
	 * @param flag if true, the elementalist dialog is displayed; otherwise it
	 *            is invisible
	 */
	public void showElementalistDialog(final boolean flag) {
		msgElements.setVisible(flag);
	}
	/**
	 * Toggles the display of the 2nd elementalist dialog.
	 * @param flag if true, the 2nd elementalist dialog is displayed; otherwise 
	 * it is invisible
	 */
	public void showElementalistDialog2(final boolean flag) {
		msgElements2.setVisible(flag);
	}
}

final class GenderOptions extends PortraitPagePanel {
	/** the "Done" button. */
	private Button	btn;
	/** Creates a new instance of {@link GenderOptions}. */
	GenderOptions() {
		super(Panel.PORTRAIT_CENTER);

		PagePanel row1 = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		row1.setHorizontalAlignment(Panel.TEXT_JUSTIFY);
		row1.setMinimumWidth(
				DWPCViewer.getInstance().getPreferredSize().width - 10);
		row1.addChild(UtilityMethods.getInstance().getSpacer(1, 38));
		Button b1 = UIFactory.getInstance().getStandardButton("Male");
		b1.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().setGender(
						DWConsts.GENDER_MALE);
				btn.setActive(true);
			}
		});
		b1.setHighlightable(true);
		b1.setHighlightBorder(new H1HighlightBorder());
		row1.addChild(b1);
		row1.addChild(UtilityMethods.getInstance().getSpacer(1, 38));

		Button b2 = UIFactory.getInstance().getStandardButton("Female");
		b2.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().setGender(
						DWConsts.GENDER_FEMALE);
				btn.setActive(true);
			}
		});
		b2.setHighlightable(true);
		b2.setHighlightBorder(new H1HighlightBorder());
		row1.addChild(b2);
		row1.addChild(UtilityMethods.getInstance().getSpacer(1, 38));

		super.addChild(row1);

		btn = UIFactory.getInstance().getStandardButton("Done");
		btn.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().nextStep();
			}
		});
		btn.setHighlightable(true);
		btn.setHighlightBorder(new H1HighlightBorder());
		btn.setActive(false);
		super.addChild(btn);
	}
}

final class MSGWindow3 extends PortraitPagePanel {
	private Button		b;
	private Label		l;
	private TextField	tf;
	MSGWindow3() {
		super(Panel.PORTRAIT_CENTER);

		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		l = UIFactory.getInstance().getStandardH2Label("");
		l.setMinimumSize(170, 19);
		super.addChild(l);

		// 10px spacer
		super.addChild(UtilityMethods.getInstance().getSpacer(
				10, 10));

		// text field
		tf = new TextField(ProjectConstants.getInstance().getFontH1(), 20);
		super.addChild(tf);

		// 20px spacer
		super.addChild(UtilityMethods.getInstance().getSpacer(
				10, 10));

		// buttons
		PagePanel p = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		p.setMinimumWidth(200);
		p.setHorizontalAlignment(GuiComponent.TEXT_JUSTIFY);
		Button b1 = UIFactory.getInstance().getStandardButton("Random Name");
		b1.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				try {
					int tl = tf.getValue().length();
					for (int i = 0; i < tl; i++) {
						tf.removeCharacter();
					}
					int g = DWCharCreationScreen.getInstance().getGender();
					int n = DWConsts.GENDER_NAMES[g].length;
					int rnd = Diceroller.getInstance().rolldX(n) - 1;
					char[] name = DWConsts.GENDER_NAMES[g][rnd];
					for (int i = 0; i < name.length; i++) {
						tf.addCharacter(name[i]);
					}
					name = null;
					b.setActive(true);
				} catch (Exception ex) {
					JOGLErrorHandler.getInstance().fatalError(ex);
				}
			}
		});
		b1.setHighlightable(true);
		b1.setHighlightBorder(new H1HighlightBorder());
		p.addChild(b1);

		b = UIFactory.getInstance().getStandardButton("Done");
		b.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().setName(tf.getValue());
				DWCharCreationScreen.getInstance().nextStep();
			}
		});
		b.setActive(false);
		b.setHighlightBorder(new H1HighlightBorder());
		p.addChild(b);

		Button b3 = UIFactory.getInstance().getStandardButton("Reset Gender");
		b3.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().prevStep();
			}
		});
		b3.setHighlightable(true);
		b3.setHighlightBorder(new H1HighlightBorder());
		p.addChild(b3);
		super.addChild(p);

		super.setBorder(new VXBorder());
		sb.returnToPool();
	}
	public void addCharacter(final char c) throws Exception {
		b.setActive(true);
		tf.addCharacter(c);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void prepareForRendering() throws Exception {
		super.prepareForRendering();
	}
	public void removeCharacter() throws Exception {
		tf.removeCharacter();
		if (tf.getValue().length() > 0) {
			b.setActive(true);
		} else {
			b.setActive(false);
		}
	}
	public void setButtonActive(final boolean flag) {
		b.setActive(flag);
	}
	public void updateLabel(final int g) {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		sb.append("What is ");
		sb.append(DWConsts.GENDER_POSSESSIVE[g]);
		sb.append(" name?");
		l.setText(sb.toString());
		sb.returnToPool();
	}
}

final class MSGWindow4 extends PortraitPagePanel {
	private Button	b;
	/** the intelligence value label. */
	private Label	lblIntelligence;
	/** the looks value label. */
	private Label	lblLooks;
	/** the psychic talent value label. */
	private Label	lblPsychicTalent;
	/** the reflexes value label. */
	private Label	lblReflexes;
	/** the strength value label. */
	private Label	lblStrength;
	MSGWindow4() {
		super(Panel.PORTRAIT_CENTER);

		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		sb.append("Each character is initially defined by their scores ");
		sb.append("in five characteristics: STRENGTH, REFLEXES, ");
		sb.append("INTELLIGENCE, PSYCHIC TALENT, and LOOKS. These scores ");
		sb.append("range from a minimum of 3 to a maximum of 18.");
		Label l = UIFactory.getInstance().getStandardH2Label(sb.toString());
		l.setMaximumWidth(380);
		super.addChild(l);

		// 10px spacer
		super.addChild(UtilityMethods.getInstance().getSpacer(
				10, 10));

		// text field
		super.addChild(getCharacteristicsPanel());

		// 20px spacer
		super.addChild(UtilityMethods.getInstance().getSpacer(
				10, 10));

		// buttons
		PagePanel p = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		p.setMinimumWidth(200);
		p.setHorizontalAlignment(GuiComponent.TEXT_JUSTIFY);
		Button b1 = UIFactory.getInstance().getStandardButton("Roll Scores");
		b1.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				try {
					lblStrength.setText(Integer.toString(
							DWPlayer.getInstance().rollCharacteristicScore()));
					lblReflexes.setText(Integer.toString(
							DWPlayer.getInstance().rollCharacteristicScore()));
					lblIntelligence.setText(Integer.toString(
							DWPlayer.getInstance().rollCharacteristicScore()));
					lblPsychicTalent.setText(Integer.toString(
							DWPlayer.getInstance().rollCharacteristicScore()));
					lblLooks.setText(Integer.toString(
							DWPlayer.getInstance().rollCharacteristicScore()));
					b.setActive(true);
				} catch (Exception ex) {
					JOGLErrorHandler.getInstance().fatalError(ex);
				}
			}
		});
		b1.setHighlightable(true);
		b1.setHighlightBorder(new H1HighlightBorder());
		p.addChild(b1);

		b = UIFactory.getInstance().getStandardButton("Done");
		b.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				try {
					int s = Integer.parseInt(lblStrength.getText());
					int r = Integer.parseInt(lblReflexes.getText());
					int i = Integer.parseInt(lblIntelligence.getText());
					int p = Integer.parseInt(lblPsychicTalent.getText());
					int l = Integer.parseInt(lblLooks.getText());
					DWCharCreationScreen.getInstance().setCharacteristics(
							s, r, i, p, l);
					DWCharCreationScreen.getInstance().nextStep();
				} catch (Exception ex) {
					JOGLErrorHandler.getInstance().fatalError(ex);
				}
			}
		});
		b.setActive(false);
		b.setHighlightBorder(new H1HighlightBorder());
		p.addChild(b);

		Button b3 = UIFactory.getInstance().getStandardButton("Change Name");
		b3.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().prevStep();
			}
		});
		b3.setHighlightable(true);
		b3.setHighlightBorder(new H1HighlightBorder());
		p.addChild(b3);
		super.addChild(p);

		super.setBorder(new VXBorder());
		sb.returnToPool();
	}
	private PagePanel getCharacteristicsPanel() {
		PagePanel p = new PortraitPagePanel(Panel.PORTRAIT_CENTER);

		PagePanel row1 = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		// STR
		Label l1 = UIFactory.getInstance().getStandardH1Label("STR");
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		sb.append("STRENGTH-\nAffects ATTACK and DEFENCE, and is the ");
		sb.append("favored characteristic of KNIGHTs and BARBARIANs");
		l1.setTooltipText(sb.toString());
		sb.setLength(0);
		row1.addChild(l1);
		// 3px spacer
		row1.addChild(UtilityMethods.getInstance().getSpacer(3, 3));
		// STAT
		lblStrength = DWPCViewer.getInstance().getDWStatsLabel();
		row1.addChild(lblStrength);
		// 38px spacer
		row1.addChild(UtilityMethods.getInstance().getSpacer(38, 38));
		// INT
		Label l3 = UIFactory.getInstance().getStandardH1Label("INT");
		sb.append("INTELLIGENCE-\nAffects ATTACK, DEFENCE, MAGICAL ATTACK, ");
		sb.append("and MAGICAL DEFENCE");
		l3.setTooltipText(sb.toString());
		sb.setLength(0);
		row1.addChild(l3);
		// 3px spacer
		row1.addChild(UtilityMethods.getInstance().getSpacer(3, 3));
		// STAT
		lblIntelligence = DWPCViewer.getInstance().getDWStatsLabel();
		row1.addChild(lblIntelligence);
		p.addChild(row1);

		// ROW 2
		PagePanel row2 = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		// REF
		Label l2 = UIFactory.getInstance().getStandardH1Label("REF");
		sb.append("RELEXES-\nAffects ATTACK, DEFENCE, EVASION, and STEALTH, ");
		sb.append("and is the favored characteristic of ASSASSINs");
		l2.setTooltipText(sb.toString());
		sb.setLength(0);
		row2.addChild(l2);
		// 3px spacer
		row2.addChild(UtilityMethods.getInstance().getSpacer(3, 3));
		// STAT
		lblReflexes = DWPCViewer.getInstance().getDWStatsLabel();
		row2.addChild(lblReflexes);
		// 38px spacer
		row2.addChild(UtilityMethods.getInstance().getSpacer(38, 38));
		// PSY
		Label l4 = UIFactory.getInstance().getStandardH1Label("PSY");
		sb.append("PSYCHIC TALENT-\nAffects MAGICAL DEFENCE and PERCEPTION ");
		sb.append("and is the favored characteristic of ELEMENTALISTs, ");
		sb.append("MYSTICs, SORCERERs, and WARLOCKs. Characters with a ");
		sb.append("PSYCHIC TALENT of 8 or less cannot use magic");
		l4.setTooltipText(sb.toString());
		sb.setLength(0);
		row2.addChild(l4);
		// 3px spacer
		row2.addChild(UtilityMethods.getInstance().getSpacer(3, 3));
		// STAT
		lblPsychicTalent = DWPCViewer.getInstance().getDWStatsLabel();
		row2.addChild(lblPsychicTalent);
		p.addChild(row2);
		// ROW 3
		PagePanel row3 = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		// LOO
		Label l5 = UIFactory.getInstance().getStandardH1Label("LOO");
		sb.append("LOOKS-\nAffects how non-player characters (NPCs) react");
		l5.setTooltipText(sb.toString());
		sb.setLength(0);
		row3.addChild(l5);
		// 3px spacer
		row3.addChild(UtilityMethods.getInstance().getSpacer(3, 3));
		// STAT
		lblLooks = DWPCViewer.getInstance().getDWStatsLabel();
		row3.addChild(lblLooks);
		p.addChild(row3);

		sb.returnToPool();
		return p;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void prepareForRendering() throws Exception {
		super.prepareForRendering();
	}
	public void setButtonActive(final boolean flag) {
		b.setActive(flag);
	}
}

final class MSGWindowElementalists extends PortraitPagePanel {
	/** the chosen profession. */
	private int	profession;
	/** Creates a new instance of {@link MSGWindowElementalists}. */
	MSGWindowElementalists() {
		super(Panel.PORTRAIT_CENTER);

		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		sb.append("Please choose which ELEMENT to specialize in:");
		Label l = UIFactory.getInstance().getStandardH2Label(sb.toString());
		l.setMaximumWidth(380);
		super.addChild(l);

		// 10px spacer
		super.addChild(UtilityMethods.getInstance().getSpacer(
				10, 10));

		// text field
		super.addChild(getElementsPanel());

		// 20px spacer
		super.addChild(UtilityMethods.getInstance().getSpacer(
				10, 10));

		super.setBorder(new VXBorder());
		sb.returnToPool();
	}
	private PagePanel getElementsPanel() {
		PagePanel p = new PortraitPagePanel(Panel.PORTRAIT_CENTER);

		PagePanel row1 = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		final int minwidth = 120;
		// AIR
		PagePanel p1 = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		p1.setMinimumWidth(minwidth);
		Button b1 = UIFactory.getInstance().getStandardH1Button("AIR");
		b1.setHighlightBorder(new H1HighlightBorder());
		b1.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				// set the profession
				DWCharCreationScreen.getInstance().setProfession(
						DWConsts.PROF_ELEMENTALIST_AIR);
				DWCharCreationScreen.getInstance().showElementalistDialog(
						false);
			}
		});
		p1.addChild(b1);
		row1.addChild(p1);
		// 38px spacer
		row1.addChild(UtilityMethods.getInstance().getSpacer(38, 38));
		// DARKNESS
		PagePanel p2 = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		p2.setMinimumWidth(minwidth);
		Button b2 = UIFactory.getInstance().getStandardH1Button("DARKNESS");
		b2.setHighlightBorder(new H1HighlightBorder());
		b2.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().setProfession(
						DWConsts.PROF_ELEMENTALIST_DARKNESS);
				// hide this window
				DWCharCreationScreen.getInstance().showElementalistDialog(
						false);
				// show the next window
				DWCharCreationScreen.getInstance().showElementalistDialog2(
						true);
			}
		});
		p2.addChild(b2);
		row1.addChild(p2);

		// ROW 2
		PagePanel row2 = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		// EARTH
		PagePanel p3 = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		p3.setMinimumWidth(minwidth);
		Button b3 = UIFactory.getInstance().getStandardH1Button("EARTH");
		b3.setHighlightBorder(new H1HighlightBorder());
		b3.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().setProfession(
						DWConsts.PROF_ELEMENTALIST_EARTH);
				DWCharCreationScreen.getInstance().showElementalistDialog(
						false);
			}
		});
		p3.addChild(b3);
		row2.addChild(p3);
		// 38px spacer
		row2.addChild(UtilityMethods.getInstance().getSpacer(38, 38));
		// FIRE
		PagePanel p4 = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		p4.setMinimumWidth(minwidth);
		Button b4 = UIFactory.getInstance().getStandardH1Button("FIRE");
		b4.setHighlightBorder(new H1HighlightBorder());
		b4.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().setProfession(
						DWConsts.PROF_ELEMENTALIST_FIRE);
				DWCharCreationScreen.getInstance().showElementalistDialog(
						false);
			}
		});
		p4.addChild(b4);
		row2.addChild(p4);

		Button b7 = UIFactory.getInstance().getStandardH1Button("WATER");
		b7.setHighlightBorder(new H1HighlightBorder());
		b7.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().setProfession(
						DWConsts.PROF_ELEMENTALIST_WATER);
				DWCharCreationScreen.getInstance().showElementalistDialog(
						false);
			}
		});
		p.addChild(row1);
		p.addChild(row2);
		p.addChild(b7);
		return p;
	}
}
/**
 * The 2nd dialog window displayed for the Elementalists profession.
 * @author Donald
 *
 */
final class MSGWindowElementalists2 extends PortraitPagePanel {
	/** the chosen elements. */
	private int[] elements = new int[]{ -1, -1 };
	/**
	 * Gets the chosen elements.
	 * @return int[]
	 */
	public int[] getElements() {
		return elements;
	}
	/** the list of buttons displayed. */
	private Button[] btnElements = new Button[4];
	private Button btnDone;
	private Button btnReset;
	/** Creates a new instance of {@link MSGWindowElementalists}. */
	MSGWindowElementalists2() {
		super(Panel.PORTRAIT_CENTER);

		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		sb.append("Please choose two subsidiary ELEMENTs to specialize in:");
		Label l = UIFactory.getInstance().getStandardH2Label(sb.toString());
		l.setMaximumWidth(380);
		super.addChild(l);

		// 10px spacer
		super.addChild(UtilityMethods.getInstance().getSpacer(
				10, 10));

		// text field
		super.addChild(getElementsPanel());

		// 20px spacer
		super.addChild(UtilityMethods.getInstance().getSpacer(
				10, 10));

		super.setBorder(new VXBorder());
		sb.returnToPool();
	}
	/** flag indicating the form has been completed. */
	private boolean formCompleted = false;
	/** Checks to see if the form has been completely filled out yet. */
	private void check() {
		if (elements[0] != -1 && elements[1] != -1) {
			btnReset.setActive(true);
			btnDone.setActive(true);
			formCompleted = true;
		} else if (elements[0] != -1 || elements[1] != -1) {
			btnReset.setActive(true);
			btnDone.setActive(false);
			formCompleted = false;
		} else {
			btnReset.setActive(false);
			btnDone.setActive(false);
			formCompleted = false;
		}
	}
	/** Resets the form. */
	public void reset() {
		for (int i = 0; i < btnElements.length; i++) {
			btnElements[i].setActive(true);
			btnElements[i].clearSpriteFlags();
		}
		this.btnReset.setActive(false);
		this.btnDone.setActive(false);
		this.elements[0] = -1;
		this.elements[1] = -1;
		formCompleted = false;
	}
	private PagePanel getElementsPanel() {
		PagePanel p = new PortraitPagePanel(Panel.PORTRAIT_CENTER);

		PagePanel row1 = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		final int minwidth = 86;
		// AIR
		PagePanel p1 = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		p1.setMinimumWidth(minwidth);
		btnElements[0] = UIFactory.getInstance().getStandardH1Button("AIR");
		btnElements[0].setHighlightBorder(new H1HighlightBorder());
		btnElements[0].addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				if (!formCompleted) {
					if (elements[0] == -1) {
						elements[0] = DWConsts.ELEM_AIR;
					} else {
						elements[1] = DWConsts.ELEM_AIR;						
					}
					btnElements[0].setActive(false);
					btnElements[0].assignSpriteFlag(
							SpriteBase.FLAG_SPRITE_CHANGE_RED);
					btnElements[0].assignSpriteFlag(
							SpriteBase.FLAG_SPRITE_CHANGE_GREEN);
					btnElements[0].assignSpriteFlag(
							SpriteBase.FLAG_SPRITE_CHANGE_BLUE);
					btnElements[0].setModRGB(2f, 0f, 0f);
					check();
				}
			}
		});
		p1.addChild(btnElements[0]);
		row1.addChild(p1);
		// 38px spacer
		row1.addChild(UtilityMethods.getInstance().getSpacer(38, 38));
		// DARKNESS
		PagePanel p2 = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		p2.setMinimumWidth(minwidth);
		btnElements[1] = UIFactory.getInstance().getStandardH1Button("EARTH");
		btnElements[1].setHighlightBorder(new H1HighlightBorder());
		btnElements[1].addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				if (!formCompleted) {
					if (elements[0] == -1) {
						elements[0] = DWConsts.ELEM_EARTH;
					} else {
						elements[1] = DWConsts.ELEM_EARTH;						
					}
					btnElements[1].setActive(false);
					btnElements[1].assignSpriteFlag(
							SpriteBase.FLAG_SPRITE_CHANGE_RED);
					btnElements[1].assignSpriteFlag(
							SpriteBase.FLAG_SPRITE_CHANGE_GREEN);
					btnElements[1].assignSpriteFlag(
							SpriteBase.FLAG_SPRITE_CHANGE_BLUE);
					btnElements[1].setModRGB(2f, 0f, 0f);
					check();
				}
			}
		});
		p2.addChild(btnElements[1]);
		row1.addChild(p2);

		// ROW 2
		PagePanel row2 = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		// EARTH
		PagePanel p3 = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		p3.setMinimumWidth(minwidth);
		btnElements[2] = UIFactory.getInstance().getStandardH1Button("FIRE");
		btnElements[2].setHighlightBorder(new H1HighlightBorder());
		btnElements[2].addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				if (!formCompleted) {
					if (elements[0] == -1) {
						elements[0] = DWConsts.ELEM_FIRE;
					} else {
						elements[1] = DWConsts.ELEM_FIRE;						
					}
					btnElements[2].setActive(false);
					btnElements[2].assignSpriteFlag(
							SpriteBase.FLAG_SPRITE_CHANGE_RED);
					btnElements[2].assignSpriteFlag(
							SpriteBase.FLAG_SPRITE_CHANGE_GREEN);
					btnElements[2].assignSpriteFlag(
							SpriteBase.FLAG_SPRITE_CHANGE_BLUE);
					btnElements[2].setModRGB(2f, 0f, 0f);
					check();
				}
			}
		});
		p3.addChild(btnElements[2]);
		row2.addChild(p3);
		// 38px spacer
		row2.addChild(UtilityMethods.getInstance().getSpacer(38, 38));
		// FIRE
		PagePanel p4 = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		p4.setMinimumWidth(minwidth);
		btnElements[3] = UIFactory.getInstance().getStandardH1Button("WATER");
		btnElements[3].setHighlightBorder(new H1HighlightBorder());
		btnElements[3].addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				if (!formCompleted) {
					if (elements[0] == -1) {
						elements[0] = DWConsts.ELEM_WATER;
					} else {
						elements[1] = DWConsts.ELEM_WATER;						
					}
					btnElements[3].setActive(false);
					btnElements[3].assignSpriteFlag(
							SpriteBase.FLAG_SPRITE_CHANGE_RED);
					btnElements[3].assignSpriteFlag(
							SpriteBase.FLAG_SPRITE_CHANGE_GREEN);
					btnElements[3].assignSpriteFlag(
							SpriteBase.FLAG_SPRITE_CHANGE_BLUE);
					btnElements[3].setModRGB(2f, 0f, 0f);
					check();
				}
			}
		});
		p4.addChild(btnElements[3]);
		row2.addChild(p4);
		
		// ROW 3
		PagePanel row3 = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		// EARTH
		PagePanel p5 = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		p5.setMinimumWidth(minwidth);
		this.btnDone = UIFactory.getInstance().getStandardH1Button("DONE");
		btnDone.setHighlightBorder(new H1HighlightBorder());
		btnDone.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				// hide this window
				DWCharCreationScreen.getInstance().showElementalistDialog2(
						false);
				// show the previous window
				DWCharCreationScreen.getInstance().showElementalistDialog(
						false);
			}
		});
		btnDone.setActive(false);
		p5.addChild(btnDone);
		row3.addChild(p5);
		// 38px spacer
		row3.addChild(UtilityMethods.getInstance().getSpacer(38, 38));
		// FIRE
		PagePanel p6 = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		p6.setMinimumWidth(minwidth);
		btnReset = UIFactory.getInstance().getStandardH1Button("RESET");
		btnReset.setHighlightBorder(new H1HighlightBorder());
		btnReset.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				reset();
			}
		});
		btnReset.setActive(false);
		p6.addChild(btnReset);
		row3.addChild(p6);
		
		p.addChild(row1);
		p.addChild(row2);
		p.addChild(row3);
		return p;
	}
}

/**
 * The panel displaying Professions to choose from.
 * @author Donald
 */
final class ProfessionOptions extends PortraitPagePanel {
	/** the "Done" button. */
	private Button	btn;
	/** the Assassin button. */
	private Button	btnAssassin;
	/** the Elementalist button. */
	private Button	btnElementalist;
	/** the Mystic button. */
	private Button	btnMystic;
	/** the Sorcerer button. */
	private Button	btnSorcerer;
	/** the Warlock button. */
	private Button	btnWarlock;
	/** Creates a new instance of {@link GenderOptions}. */
	ProfessionOptions() {
		super(Panel.PORTRAIT_CENTER);

		super.addChild(createRow(
				DWConsts.PROF_KNIGHT,
				DWConsts.PROF_BARBARIAN,
				DWConsts.PROF_SORCERER
				));
		super.addChild(createRow(
				DWConsts.PROF_MYSTIC,
				DWConsts.PROF_ELEMENTALIST_AIR,
				DWConsts.PROF_WARLOCK
				));
		super.addChild(createRow(DWConsts.PROF_ASSASSIN));

		PagePanel row = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		row.setHorizontalAlignment(Panel.TEXT_JUSTIFY);
		row.setMinimumWidth(
				DWPCViewer.getInstance().getPreferredSize().width - 10);

		row.addChild(UtilityMethods.getInstance().getSpacer(1, 38));
		btn = UIFactory.getInstance().getStandardButton("Done");
		btn.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().nextStep();
			}
		});
		btn.setHighlightable(true);
		btn.setHighlightBorder(new H1HighlightBorder());
		btn.setActive(false);
		row.addChild(btn);
		row.addChild(UtilityMethods.getInstance().getSpacer(1, 38));
		Button b = UIFactory.getInstance().getStandardButton("Re-roll Scores");
		b.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().prevStep();
			}
		});
		b.setHighlightable(true);
		b.setHighlightBorder(new H1HighlightBorder());
		b.setActive(true);
		row.addChild(b);
		row.addChild(UtilityMethods.getInstance().getSpacer(1, 38));
		super.addChild(row);
	}
	/**
	 * Creates a row of buttons.
	 * @param professions the professions displayes on the row
	 * @return {@link Panel}
	 */
	private Panel createRow(final int... professions) {
		PagePanel row1 = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		row1.setHorizontalAlignment(Panel.TEXT_JUSTIFY);
		row1.setMinimumWidth(
				DWPCViewer.getInstance().getPreferredSize().width - 10);
		for (int i = 0; i < professions.length; i++) {
			final int val = professions[i];
			row1.addChild(UtilityMethods.getInstance().getSpacer(1, 38));
			if (val == DWConsts.PROF_ASSASSIN) {
				btnAssassin = UIFactory.getInstance().getStandardButton(
						DWConsts.PROFESSIONS[val]);
				btnAssassin.addAction(new Action() {
					/**
					 * {@inheritDoc}
					 */
					@Override
					public void performAction() {
						DWCharCreationScreen.getInstance().setProfession(val);
						btn.setActive(true);
					}
				});		
				btnAssassin.setHighlightable(true);
				btnAssassin.setHighlightBorder(new H1HighlightBorder());
				row1.addChild(btnAssassin);		
			} else if (val >= DWConsts.PROF_ELEMENTALIST_AIR 
					&& val <= DWConsts.PROF_ELEMENTALIST_WATER) {
				btnElementalist = 
					UIFactory.getInstance().getStandardButton("Elementalist");
				btnElementalist.addAction(new Action() {
					/**
					 * {@inheritDoc}
					 */
					@Override
					public void performAction() {
						DWCharCreationScreen.getInstance()
								.showElementalistDialog(true);
						btn.setActive(true);
					}
				});
				btnElementalist.setHighlightable(true);
				btnElementalist.setHighlightBorder(new H1HighlightBorder());
				row1.addChild(btnElementalist);
			} else if (val == DWConsts.PROF_MYSTIC) {
				btnMystic = UIFactory.getInstance().getStandardButton(
						DWConsts.PROFESSIONS[val]);
				btnMystic.addAction(new Action() {
					/**
					 * {@inheritDoc}
					 */
					@Override
					public void performAction() {
						DWCharCreationScreen.getInstance().setProfession(val);
						btn.setActive(true);
					}
				});		
				btnMystic.setHighlightable(true);
				btnMystic.setHighlightBorder(new H1HighlightBorder());
				row1.addChild(btnMystic);		
			} else if (val == DWConsts.PROF_SORCERER) {
				btnSorcerer = UIFactory.getInstance().getStandardButton(
						DWConsts.PROFESSIONS[val]);
				btnSorcerer.addAction(new Action() {
					/**
					 * {@inheritDoc}
					 */
					@Override
					public void performAction() {
						DWCharCreationScreen.getInstance().setProfession(val);
						btn.setActive(true);
					}
				});		
				btnSorcerer.setHighlightable(true);
				btnSorcerer.setHighlightBorder(new H1HighlightBorder());
				row1.addChild(btnSorcerer);		
			} else if (val == DWConsts.PROF_WARLOCK) {
				btnWarlock = UIFactory.getInstance().getStandardButton(
						DWConsts.PROFESSIONS[val]);
				btnWarlock.addAction(new Action() {
					/**
					 * {@inheritDoc}
					 */
					@Override
					public void performAction() {
						DWCharCreationScreen.getInstance().setProfession(val);
						btn.setActive(true);
					}
				});		
				btnWarlock.setHighlightable(true);
				btnWarlock.setHighlightBorder(new H1HighlightBorder());
				row1.addChild(btnWarlock);		
			} else {
				Button b = null;
				b = UIFactory.getInstance().getStandardButton(
						DWConsts.PROFESSIONS[val]);
				b.addAction(new Action() {
					/**
					 * {@inheritDoc}
					 */
					@Override
					public void performAction() {
						DWCharCreationScreen.getInstance().setProfession(val);
						btn.setActive(true);
					}
				});
				b.setHighlightable(true);
				b.setHighlightBorder(new H1HighlightBorder());
				row1.addChild(b);
			}
			row1.addChild(UtilityMethods.getInstance().getSpacer(1, 38));
		}
		return row1;
	}
	/** Disables the Assassin button. */
	private void disableAssassin() {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		btnAssassin.setActive(false);
		sb.append("Reflexes must be at least 12, and Intelligence and ");
		sb.append("Psychic Talent must both be at least 9 to qualify as an ");
		sb.append("Assassin");
		btnAssassin.setTooltipText(sb.toString());
		sb.returnToPool();
	}
	/** Disables the Elementalist button. */
	private void disableElementalist() {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		btnElementalist.setActive(false);
		sb.append("Intelligence and Psychic Talent must both be at least ");
		sb.append("9 to become an Elementalist");
		btnElementalist.setTooltipText(sb.toString());
		sb.returnToPool();
	}
	/** Disables the Mystic button. */
	private void disableMystic() {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		btnMystic.setActive(false);
		sb.append("Psychic Talent must both be at least ");
		sb.append("9 to qualify as a Mystic");
		btnMystic.setTooltipText(sb.toString());
		sb.returnToPool();
	}
	/** Disables the Sorcerer button. */
	private void disableSorcerer() {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		btnSorcerer.setActive(false);
		sb.append("Intelligence and Psychic Talent must both be at least ");
		sb.append("9 to qualify as a Sorcerer");
		btnSorcerer.setTooltipText(sb.toString());
		sb.returnToPool();
	}
	/** Disables the Warlock button. */
	private void disableWarlock() {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		btnWarlock.setActive(false);
		sb.append("Intelligence must be at least 11 and Psychic Talent must ");
		sb.append("be at least 9 to be a Warlock");
		btnWarlock.setTooltipText(sb.toString());
		sb.returnToPool();
	}
	/** Enables the Assassin button. */
	private void enableAssassin() {
		btnAssassin.setActive(true);
		btnAssassin.setTooltipText("");
	}
	/** Enables the Elementalist button. */
	private void enableElementalist() {
		btnElementalist.setActive(true);
		btnElementalist.setTooltipText("");
	}
	/** Enables the Mystic button. */
	private void enableMystic() {
		btnMystic.setActive(true);
		btnMystic.setTooltipText("");
	}
	/** Enables the Sorcerer button. */
	private void enableSorcerer() {
		btnSorcerer.setActive(true);
		btnSorcerer.setTooltipText("");
	}
	/** Enables the Warlock button. */
	private void enableWarlock() {
		btnWarlock.setActive(true);
		btnWarlock.setTooltipText("");
	}
	/** Refactors the panel, enabling/disabling buttons as needed. */
	public void refactor() {
		final int nine = 9, eleven = 11, twelve = 12;
		if (DWCharCreationScreen.getInstance().getPsychicTalent() < nine) {
			disableSorcerer();
			disableMystic();
			disableElementalist();
			disableWarlock();
			disableAssassin();
		} else {
			enableMystic();
			if (DWCharCreationScreen.getInstance().getIntelligence() < nine) {
				disableSorcerer();
				disableElementalist();
				disableWarlock();
				disableAssassin();
			} else {
				enableSorcerer();
				enableElementalist();
				if (DWCharCreationScreen.getInstance().getIntelligence() 
						< eleven) {
					disableWarlock();
				} else {
					enableWarlock();
				}
				if (DWCharCreationScreen.getInstance().getReflexes() < twelve) {
					disableAssassin();
				} else {
					enableAssassin();
				}
			}
		}
	}
}
/**
 * Start options only has one button.
 * @author Donald
 */
final class StartOptions extends PortraitPagePanel {
	/** Creates a new instance of {@link StartOptions}. */
	StartOptions() {
		super(Panel.PORTRAIT_CENTER);
		final int ten = 10, nineteen = 19;
		super.setMinimumWidth(
				DWPCViewer.getInstance().getPreferredSize().width - ten);
		Button b = UIFactory.getInstance().getStandardButton("Begin");
		b.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				DWCharCreationScreen.getInstance().nextStep();
			}
		});
		b.setHighlightable(true);
		b.setHighlightBorder(new H1HighlightBorder());
		super.addChild(b);
		super.addChild(UtilityMethods.getInstance().getSpacer(1, nineteen));
	}
}
/**
 * The wizard's steps panel. 199px wide.
 * @author Donald
 */
final class StepsPanel extends PortraitPagePanel {
	/** the arrow border. */
	private GuiBorder	bdrArrow	= new H1SelectionBorder();
	/** the arrow border. */
	private GuiBorder	bdrEmpty	= new EmptyBorder(
											0,
											GlobalConsts.INT_018,
											0,
											GlobalConsts.INT_018
											);
	/** the list of labels. */
	private Label[]		labels		= new Label[GlobalConsts.INT_005];
	/** Creates a new instance of {@link StepsPanel}. */
	StepsPanel() {
		super(Panel.PORTRAIT_LEFT);

		// GENDER - 96px wide by 19px high
		labels[0] = UIFactory.getInstance().getStandardH1Label("GENDER");
		labels[0].setBorder(bdrEmpty);
		super.addChild(labels[0]);

		// 10px spacer
		super.addChild(UtilityMethods.getInstance().getSpacer(
				GlobalConsts.INT_010, GlobalConsts.INT_010));

		// CHARACTERISTICS - 186px wide by 19px high
		labels[1] =
				UIFactory.getInstance().getStandardH1Label("CHARACTERISTICS");
		labels[1].setBorder(bdrEmpty);
		super.addChild(labels[1]);

		// 10px spacer
		super.addChild(UtilityMethods.getInstance().getSpacer(
				GlobalConsts.INT_010, GlobalConsts.INT_010));

		// PROFESSION - 136px wide by 19px high
		labels[2] =
				UIFactory.getInstance().getStandardH1Label("PROFESSION");
		labels[2].setBorder(bdrEmpty);
		super.addChild(labels[2]);

		// 10px spacer
		super.addChild(UtilityMethods.getInstance().getSpacer(
				GlobalConsts.INT_010, GlobalConsts.INT_010));

		// NAME - 76px wide by 19px high
		labels[GlobalConsts.INT_003] = 
			UIFactory.getInstance().getStandardH1Label("NAME");
		labels[GlobalConsts.INT_003].setBorder(bdrEmpty);
		super.addChild(labels[GlobalConsts.INT_003]);

		// 10px spacer
		super.addChild(UtilityMethods.getInstance().getSpacer(
				GlobalConsts.INT_010, GlobalConsts.INT_010));

		// BACKGROUND - 136px wide by 19px high
		labels[GlobalConsts.INT_004] =
				UIFactory.getInstance().getStandardH1Label("BACKGROUND");
		labels[GlobalConsts.INT_004].setBorder(bdrEmpty);
		super.addChild(labels[GlobalConsts.INT_004]);
		
		
		final int thirtyeight = 38;
		// 38px spacer
		super.addChild(UtilityMethods.getInstance().getSpacer(
				thirtyeight, thirtyeight));

		// Cancel button
		Button b = UIFactory.getInstance().getStandardButton("Cancel");
		b.addAction(new Action() {
			/**
			 * {@inheritDoc}
			 */
			@Override
			public void performAction() {
				AHQApplet.getInstance().exit();
			}
		});
		b.setHighlightable(true);
		b.setHighlightBorder(new H1HighlightBorder());
		super.addChild(b);
		try {
			// add panel's border, 16px wide, 13px high
			super.setBorder(new FlexibleImageBorder(
					new int[] {
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_bl"), // bottom-left
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_br_half_2"), // b-r
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_b"), // bottom
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_tl_full"), // top-l
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_tr_half"), // top-r
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_t_1"), // top
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_border_l"), // left
							SpriteImageObjectFactory.getInstance()
									.getImageRefId(
											"vx_flex_border_r") // right
					},
					new int[] {
							GlobalConsts.INT_005, // top
							GlobalConsts.INT_008, // left
							GlobalConsts.INT_008, // bottom
							GlobalConsts.INT_005 // right
					}
					));
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/**
	 * Set the index where the arrow should point.
	 * @param index the index
	 */
	public void setArrow(final int index) {
		for (int i = 0; i < labels.length; i++) {
			if (i == index - 1) {
				labels[i].setBorder(bdrArrow);
			} else {
				labels[i].setBorder(bdrEmpty);
			}
		}
	}
}
